Skip to content

Conversation

@nlynzaad
Copy link
Contributor

@nlynzaad nlynzaad commented Jan 19, 2026

This PR applies the same fix that was done in #6389 for Solid to React. As mentioned by @theoludwig in the comments this affects React as well and was missed by the tests.

This PR also updates and aligns the tests across React, Solid and Vue.

Summary by CodeRabbit

  • New Features

    • Added a toggle to show/hide the URL hash on the special-chars page and added a second hash-enabled link.
  • Bug Fixes

    • Made hash-based active-state matching more consistent across navigation and hydration.
  • Tests

    • Updated end-to-end tests to cover both hash links, the toggle interaction, and verification of hash content after navigation.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 19, 2026

📝 Walkthrough

Walkthrough

Adds a toggle-controlled conditional display of the current URL hash in React, Solid, and Vue starter routes; adds a second hash link and adjusts test IDs and e2e tests to toggle before asserting the hash and use containment class checks; adjusts hash-handling logic in react-router and solid-router link utilities.

Changes

Cohort / File(s) Summary
React route & tests
e2e/react-start/basic/src/routes/specialChars/hash.tsx, e2e/react-start/basic/tests/special-characters.spec.ts
Add toggleHashValue state, toggle button and conditional hash display; tests split special-hash-link into -1/-2, click toggle-hash-button before reading hash, and change some assertions to toContainClass.
Solid route & tests
e2e/solid-start/basic/src/routes/specialChars/hash.tsx, e2e/solid-start/basic/tests/special-characters.spec.ts
Replace automatic hash syncing with a boolean toggle and button-controlled display; tests updated to use special-hash-link-1/-2, toggle before asserting hash, and use toContainClass assertions.
Vue route & tests
e2e/vue-start/basic/src/routes/specialChars/hash.tsx, e2e/vue-start/basic/tests/special-characters.spec.ts
Replace function route with defineComponent exposing toggleHashValue and a toggle button for conditional hash rendering; tests updated to use two hash links and toggle before reading hash, with containment class checks.
Route link entries
e2e/*/basic/src/routes/specialChars/route.tsx (React, Solid, Vue)
Rename original special-hash-linkspecial-hash-link-1, add special-hash-link-2 (hash 'abc', includeHash: true), and update link labels (e.g., "Unicode Hash 대
React router link logic
packages/react-router/src/link.tsx
Add hydration awareness via useHydrated() and only consider the hash for active evaluation when hydrated.
Solid router link logic
packages/solid-router/src/link.tsx
Change useLinkProps to evaluate hash comparison when includeHash is set regardless of prior server/client guard (hash comparison now evaluated on server and client paths).

Sequence Diagram(s)

(Skipped.)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

package: vue-router, package: react-start-client

Suggested reviewers

  • birkskyum
  • schiller-manuel

Poem

🐇 I nudge a little toggle, peek the hash so bright,
Unicode and "abc" pop into sight,
React, Solid, Vue — I hop with glee,
Links bold or quiet, what fun to see,
A rabbit cheers for code that's light!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main fix: applying Link active properties correctly on SSR when including hash, which is the core objective across React, Solid, and Vue implementations.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud
Copy link

nx-cloud bot commented Jan 19, 2026

View your CI Pipeline Execution ↗ for commit 9b4bb13

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ✅ Succeeded 1m 33s View ↗

☁️ Nx Cloud last updated this comment at 2026-01-21 22:54:53 UTC

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jan 19, 2026

More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/arktype-adapter@6421

@tanstack/eslint-plugin-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/eslint-plugin-router@6421

@tanstack/history

npm i https://pkg.pr.new/TanStack/router/@tanstack/history@6421

@tanstack/nitro-v2-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/nitro-v2-vite-plugin@6421

@tanstack/react-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router@6421

@tanstack/react-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-devtools@6421

@tanstack/react-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-ssr-query@6421

@tanstack/react-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start@6421

@tanstack/react-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-client@6421

@tanstack/react-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-server@6421

@tanstack/router-cli

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-cli@6421

@tanstack/router-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-core@6421

@tanstack/router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools@6421

@tanstack/router-devtools-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools-core@6421

@tanstack/router-generator

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-generator@6421

@tanstack/router-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-plugin@6421

@tanstack/router-ssr-query-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-ssr-query-core@6421

@tanstack/router-utils

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-utils@6421

@tanstack/router-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-vite-plugin@6421

@tanstack/solid-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router@6421

@tanstack/solid-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-devtools@6421

@tanstack/solid-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-ssr-query@6421

@tanstack/solid-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start@6421

@tanstack/solid-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-client@6421

@tanstack/solid-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-server@6421

@tanstack/start-client-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-client-core@6421

@tanstack/start-fn-stubs

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-fn-stubs@6421

@tanstack/start-plugin-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-plugin-core@6421

@tanstack/start-server-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-core@6421

@tanstack/start-static-server-functions

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-static-server-functions@6421

@tanstack/start-storage-context

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-storage-context@6421

@tanstack/valibot-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/valibot-adapter@6421

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/TanStack/router/@tanstack/virtual-file-routes@6421

@tanstack/vue-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router@6421

@tanstack/vue-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router-devtools@6421

@tanstack/vue-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-router-ssr-query@6421

@tanstack/vue-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start@6421

@tanstack/vue-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start-client@6421

@tanstack/vue-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/vue-start-server@6421

@tanstack/zod-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/zod-adapter@6421

commit: 9b4bb13

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@packages/react-router/src/link.tsx`:
- Around line 100-105: currentHash from useRouterState is subscribed but not
used, so hash-only navigations don't trigger recomputation of href; update the
memo dependencies (where buildLocation/_options/next/href are computed) to
include currentHash (or include currentHash in next's deps) so buildLocation is
re-run on hash changes and remove the unused-variable issue—locate the code that
computes next/_options/href (the memoized block that calls buildLocation) and
add currentHash to its dependency array.

@theoludwig
Copy link

theoludwig commented Jan 20, 2026

Thank you for working on this!

Edit: I tried to test the PR using pkg.pr.new with:

"@tanstack/react-router": "https://pkg.pr.new/TanStack/router/@tanstack/react-router@6421"
"@tanstack/react-start": "https://pkg.pr.new/TanStack/router/@tanstack/react-start@6421"

However, it doesn't seem to resolve the hydratation issue. And now all my links that point to the same page are considered "active", even with includeHash: true, and exact: true.

@nlynzaad nlynzaad marked this pull request as draft January 20, 2026 01:02
@nlynzaad
Copy link
Contributor Author

Thank you for working on this!

Edit: I tried to test the PR using pkg.pr.new with:

"@tanstack/react-router": "https://pkg.pr.new/TanStack/router/@tanstack/react-router@6421"
"@tanstack/react-start": "https://pkg.pr.new/TanStack/router/@tanstack/react-start@6421"

However, it doesn't seem to resolve the hydratation issue. And now all my links that point to the same page are considered "active", even with includeHash: true, and exact: true.

picked this up during testing and hence the draft status, digging through it to find a more holistic solution

@nlynzaad nlynzaad marked this pull request as ready for review January 21, 2026 00:28
@nlynzaad
Copy link
Contributor Author

@theoludwig could you test the latest builds and advise if the problem is resolved for you. When including hashes for active options you can remove exact:true as that overrides the hash checks.

@theoludwig
Copy link

theoludwig commented Jan 21, 2026

@theoludwig could you test the latest builds and advise if the problem is resolved for you. When including hashes for active options you can remove exact:true as that overrides the hash checks.

Oh indeed, the issue is now resolved! I needed to do rm -rf "$(pnpm store path)" otherwise pnpm wouldn't pick the change from pkg.pr.new.

I end up doing something like this for checking if it needs exact: true or includeHash: true:

const SidebarItemCreate = createLink(SidebarItemRaw)
export const SidebarItem: LinkComponent<React.FC<SidebarItemRawProps>> = (props) => {
  return (
    <SidebarItemCreate
      activeProps={{
        isActive: true,
      }}
      activeOptions={{
        exact: props.hash == null,
        includeHash: props.hash != null,
      }}
      {...props}
    />
  )
}

Thank you again! Looking forward to getting this released.

@nlynzaad nlynzaad merged commit 60a30fc into main Jan 21, 2026
7 of 8 checks passed
@nlynzaad nlynzaad deleted the hash-ssr-reactivity branch January 21, 2026 22:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants